﻿using ABCNet.Authorization.Users;
using ABCNet.Extensions;
using ABCNet.NetPointFinancialLists;
using ABCNet.NetPoints.Dto;
using Abp.Application.Services.Dto;
using Abp.AutoMapper;
using Abp.Domain.Repositories;
using Abp.Linq.Extensions;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ABCNet.NetPoints
{
    public class NetPointAppService : ABCNetAppServiceBase
    {
        private readonly IRepository<NetPoint> _repository;
        private readonly IRepository<NetPointFinancialList> _financialRepository;
        private readonly IRepository<User, long> _userRepository;

        public NetPointAppService(IRepository<NetPoint> repository,
            IRepository<NetPointFinancialList> financialRepository,
            IRepository<User, long> userRepository)
        {
            _repository = repository;
            _financialRepository = financialRepository;
            _userRepository = userRepository;
        }

        /// <summary>
        /// 查询分页
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<List<NetPointDto>> GetMyNetPoints()
        {
            var query = _repository.GetAll().Where(x => x.UserId == AbpSession.UserId)
                .OrderByDescending(x => x.CreationTime);
            var lst = await query.ToListAsync();
            var dtolist = lst.MapTo<List<NetPointDto>>();
            return dtolist;
        }

        /// <summary>
        /// 查询点位收入明细分页
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<PagedResultDto<NetPointFinancialListDto>> GetNetPointFinancialPageList(FinancialQueryInput input)
        {
            var query = _financialRepository.GetAll().Where(x => x.NetPointId == input.NetPointId)
                        .WhereIf(input.PBusinessType != null && input.PBusinessType.HasValue, x => x.PBusinessType == input.PBusinessType.Value)
                        .WhereIf(input.StartDate != null && input.StartDate.HasValue, x => x.CreationTime >= input.StartDate.Value.Date)
                        .WhereIf(input.EndDate != null && input.EndDate.HasValue, x => x.CreationTime < input.EndDate.Value.Date.AddDays(1))
                        .OrderByDescending(x => x.CreationTime);
            var pageList = await query.GetPageSortListAsync<NetPointFinancialList, NetPointFinancialListDto>(input);
            return pageList;
        }

        public async Task<List<NetPointDto>> GetRelationshipMap(RelationshipMapInput input)
        {
            int id = input.Id;
            var query = _repository.GetAll();
            var userQuery = _userRepository.GetAll();
            if (id != 0)
                query = query.Where(x => x.PL1 == id);
            else if (AbpSession.AccountType == AccountTypes.后台账户)
            {
                query = query
                        .WhereIf(string.IsNullOrWhiteSpace(input.UserName), x => x.PL1 == 0)
                        .WhereIf(input.StartDate != null && input.StartDate.HasValue, x => x.CreationTime >= input.StartDate.Value.Date)
                        .WhereIf(input.EndDate != null && input.EndDate.HasValue, x => x.CreationTime < input.EndDate.Value.Date.AddDays(1));
                userQuery = userQuery.WhereIf(!string.IsNullOrWhiteSpace(input.UserName), x => EF.Functions.Like(x.UserName, $"%{input.UserName}%"));
            }
            else
                query = query.Where(x => x.UserId == AbpSession.UserId);
            var q = from np in query
                    join user in userQuery on np.UserId equals user.Id
                    orderby np.CreationTime descending
                    select new NetPointDto
                    {
                        Id = np.Id,
                        CreationTime = np.CreationTime,
                        LockedBalance = np.LockedBalance,
                        NetType = np.NetType,
                        PointType = np.PointType,
                        UserId = np.UserId,
                        TreePath = np.TreePath,
                        Layer = np.Layer,
                        UserName = user.UserName,
                        Name = user.Name,
                        IsLeaf = false,
                        NodeCount = 0 //(_repository.GetAll().Where(x => EF.Functions.Like(x.TreePath, $"{np.TreePath},{np.Id},%")).Count())
                    };
            var lst = await q.ToListAsync();
            foreach (var item in lst)
            {
                item.NodeCount = _repository.GetAll().Where(x => EF.Functions.Like(x.TreePath, $"{item.TreePath},{item.Id}%")).Count();
            }

            return lst;
        }

        private async Task<List<NetPointDto>> GetNextLevel(IQueryable<NetPoint> query)
        {
            var q = from np in query
                    join user in _userRepository.GetAll() on np.UserId equals user.Id
                    orderby np.CreationTime descending
                    select new NetPointDto
                    {
                        Id = np.Id,
                        CreationTime = np.CreationTime,
                        LockedBalance = np.LockedBalance,
                        NetType = np.NetType,
                        PointType = np.PointType,
                        UserId = np.UserId,
                        UserName = user.UserName,
                        Name = user.Name,
                        IsLeaf = false,
                        NodeCount = (_repository.GetAll().Where(x=> EF.Functions.Like(x.TreePath, $"{np.TreePath},%")).Count())
                    };
            var lst = await q.ToListAsync();
            return lst;
        }
    }
}
